package bot

import (
	"fmt"
	"encoding/json"
	"log"
	"net/http"

	"github.com/gorilla/websocket"

	"github.com/Sugobet/SGBbot/event"
)


var onGroupMessageTask = make([]func(event *event.GroupMessage), 0, 10)
var onPrivateMessageTask = make([]func(event *event.PrivateMessage), 0, 10)
var onDiscussMessageTask = make([]func(event *event.DiscussMessage), 0, 10)

var onNoticeGroupDecreaseTask = make([]func(event *event.GroupDecrease), 0, 10)
var onNoticeGroupIncreaseTask = make([]func(event *event.GroupIncrease), 0, 10)
var onNoticeGroupBanTask = make([]func(event *event.GroupBan), 0, 10)

var onRequestFriendRequestTask = make([]func(event *event.FriendRequest), 0, 10)
var onRequestGroupRequestTask = make([]func(event *event.GroupRequest), 0, 10)


// NewUpgrader .
func NewUpgrader() *websocket.Upgrader {
	return &websocket.Upgrader{}
}


func httpTurnWebSocket(w http.ResponseWriter, r *http.Request) {
	upgrader := NewUpgrader()
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal("http Turn WebSocket error:", err)
	}

	go func(conn *websocket.Conn) {
		fmt.Println(conn.RemoteAddr(), "connected /ws/event")
		for {
			_, eve, _ := conn.ReadMessage()
			var da map[string]interface{}
			err = json.Unmarshal(eve, &da)
			if err == nil {
				postType := da["post_type"]
				if postType == "message" {
					msgType := da["message_type"]
					switch{
					case msgType == "group":
						for _, fun := range onGroupMessageTask {
							struc := &event.GroupMessage{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					case msgType == "private":
						for _, fun := range onPrivateMessageTask {
							struc := &event.PrivateMessage{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					case msgType ==  "discuss":
						for _, fun := range onDiscussMessageTask {
							struc := &event.DiscussMessage{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					}
				}
				if postType == "notice"{
					msgType := da["message_type"]
					switch{
					case msgType == "group_decrease":
						for _, fun := range onNoticeGroupDecreaseTask {
							struc := &event.GroupDecrease{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					case msgType == "group_increase":
						for _, fun := range onNoticeGroupIncreaseTask {
							struc := &event.GroupIncrease{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					case msgType == "group_ban":
						for _, fun := range onNoticeGroupBanTask {
							struc := &event.GroupBan{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					}
				}
				if postType ==  "request"{
					msgType := da["message_type"]
					switch{
					case msgType == "friend":
						for _, fun := range onRequestFriendRequestTask {
							struc := &event.FriendRequest{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					case msgType == "group":
						for _, fun := range onRequestGroupRequestTask {
							struc := &event.GroupRequest{}
							json.Unmarshal(eve, struc)
							go fun(struc)
						}
					}
				}
			}
		}
	}(conn)
}


// OnGroupMessage .
func OnGroupMessage(f func(event *event.GroupMessage)) {
	onGroupMessageTask = append(onGroupMessageTask, f)
}


// OnPrivateMessage .
func OnPrivateMessage(f func(event *event.PrivateMessage)) {
	onPrivateMessageTask = append(onPrivateMessageTask, f)
}


// OnDiscussMessage .
func OnDiscussMessage(f func(event *event.DiscussMessage)) {
	onDiscussMessageTask = append(onDiscussMessageTask, f)
}


// OnNoticeGroupDecrease .
func OnNoticeGroupDecrease(f func(event *event.GroupDecrease)){
	onNoticeGroupDecreaseTask = append(onNoticeGroupDecreaseTask, f)
}


// OnNoticeGroupIncrease .
func OnNoticeGroupIncrease(f func(event *event.GroupIncrease)){
	onNoticeGroupIncreaseTask = append(onNoticeGroupIncreaseTask, f)
}


// OnNoticeGroupBan .
func OnNoticeGroupBan(f func(event *event.GroupBan)){
	onNoticeGroupBanTask = append(onNoticeGroupBanTask, f)
}


// OnRequestFriendRequest .
func OnRequestFriendRequest(f func(event *event.FriendRequest)){
	onRequestFriendRequestTask = append(onRequestFriendRequestTask, f)
}


// OnRequestGroupRequest .
func OnRequestGroupRequest(f func(event *event.GroupRequest)){
	onRequestGroupRequestTask = append(onRequestGroupRequestTask, f)
}


// Run .
func Run(addr string) {
	http.HandleFunc("/ws/event/", httpTurnWebSocket)
	http.ListenAndServe(addr, nil)
}
